package chapter05

/**
  * 函数的形参列表可以是多个, 如果函数没有形参，调用时 可以不带()
  * 形参列表和返回值列表的数据类型可以是值类型和引用类型。
  * Scala中的函数可以根据函数体最后一行代码自行推断函数返回值类型。那么在这种情况下，return关键字可以省略。
  * 因为Scala可以自行推断，所以在省略return关键字的场合，返回值类型也可以省略
  * 如果函数明确使用return关键字，那么函数返回就不能使用自行推断了,这时要明确写成 : 返回类型 = ，当然如果你什么都不写，即使有return 返回值为()
  * 如果函数明确声明无返回值（声明Unit），那么函数体中即使使用return关键字也不会有返回值。
  * 如果明确函数无返回值或不确定返回值类型，那么返回值类型可以省略(或声明为Any)
  * Scala语法中任何的语法结构都可以嵌套其他语法结构(灵活)，即：函数中可以再声明/定义函数，类中可以再声明类 ，方法中可以再声明/定义方法。
  * Scala函数的形参，在声明参数时，直接赋初始值(默认值)，这时调用函数时，如果没有指定实参，则会使用默认值。如果指定了实参，则实参会覆盖默认值。
  * 如果函数存在多个参数，每一个参数都可以设定默认值，那么这个时候，传递的参数到底是覆盖默认值，还是赋值给没有默认值的参数，就不确定了(默认按照声明顺序[从左到右])。在这种情况下，可以采用带名参数。
  * Scala 函数的形参默认是val的，因此不能在函数中进行修改。
  * Scala函数支持可变参数。
  */
object Test3_FunctionParameter {

  def main(args: Array[String]): Unit = {
    //函数的形参列表可以是多个, 如果函数没有形参，调用时 可以不带()
    println(sayHello())

    // 1.可变参数,多个参数可变参数放最后
    def f1(str1: String, str2: String*): Unit = {
      println(str1)
      println(str2)
    }

    println(f1("可", "变", "参", "数"))

    //2.Scala函数的形参，在声明参数时，直接赋初始值(默认值)，这时调用函数时，如果没有指定实参，则会使用默认值。如果指定了实参，则实参会覆盖默认值。
    def f2(name: String = "参数默认值") = {
      name
    }

    println(f2())
    println(f2("覆盖默认值"))
  }

  //3.如果函数存在多个参数，每一个参数都可以设定默认值，那么这个时候，
  // 传递的参数到底是覆盖默认值，还是赋值给没有默认值的参数，就不确定了(默认按照声明顺序[从左到右])。在这种情况下，可以采用带名参数。
  def f3(name: String = "小王", age: Int = 35) = {
    println(s"姓名$name,今年${age}岁")
    //Scala 函数的形参默认是val的，因此不能在函数中进行修改。
    //    name="343" error
  }

  f3(age = 66, name = "老王")

  //4.Scala中的函数可以根据函数体最后一行代码自行推断函数返回值类型。那么在这种情况下，return关键字可以省略。
  def sayHello() = {
    "hello"
  }

  //5.如果函数体只有一行代码,可以省略花括号
  def f4 = "这也是一个方法"

  def f5() = "这也是一个方法"

  def f6(name: String) = name

  //调用时不能加括号
  println(f4)
  //调用时括号可加可不加
  println(f5())
  println(f6("aaa"))

  // 6.匿名函数:lambda表达式 ;如果不关心名称,只关心逻辑处理,函数名(def) 可以省略
  (name: String) => {println(name)}
}
